package whf.framework.security.service;

import java.util.List;

import whf.framework.exception.CreateException;
import whf.framework.exception.DAOException;
import whf.framework.exception.FindException;
import whf.framework.exception.ServiceNotFoundException;
import whf.framework.security.dao.GroupDAO;
import whf.framework.security.dao.RoleDAO;
import whf.framework.security.dao.UserDAO;
import whf.framework.security.entity.Dept;
import whf.framework.security.entity.Group;
import whf.framework.security.entity.Role;
import whf.framework.security.entity.User;
import whf.framework.util.BeanFactory;

/**
 * @author wanghaifeng
 * @email king@126.com
 * @modify 2006-05-31
 */
public class UserServiceImp extends whf.framework.service.ServiceImp<User> implements
		UserService {

	private UserDAO userDAO;

	private GroupDAO groupDAO;
	
	private RoleDAO roleDAO;

	/**
	 * @modify wanghaifeng Aug 31, 2006 1:10:24 PM
	 * @param userDAO
	 */
	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}

	/**
	 * @param groupDAO
	 *            The groupDAO to set.
	 */
	public void setGroupDAO(GroupDAO groupDAO) {
		this.groupDAO = groupDAO;
	}

	/**
	 * @param roleDAO The roleDAO to set.
	 */
	public void setRoleDAO(RoleDAO roleDAO) {
		this.roleDAO = roleDAO;
	}

	public static UserService getUserService() throws ServiceNotFoundException {
		return (UserService) BeanFactory.getService(UserServiceImp.class);
	}

	@Override
	public void create(User entity) throws CreateException {
		Dept dept = entity.getDept();
		if(dept != null) {
			entity.setBranch(dept.getBranch());
		}
		super.create(entity);
	}

	/* (non-Javadoc)
	 * @see whf.framework.security.service.UserService#findByUsernamePassword(java.lang.String, java.lang.String)
	 */
	public User findByUsernamePassword(String username, String password)
			throws FindException {
		return userDAO.findByUsernamePassword(username, password);
	}

	/* (non-Javadoc)
	 * @see whf.framework.security.service.UserService#findByUsername(java.lang.String)
	 */
	public User findByUsername(String username) throws FindException {
		return userDAO.findByUsername(username);
	}

	/* (non-Javadoc)
	 * @see whf.framework.security.service.UserService#assignUserGroups(whf.framework.security.entity.User, java.util.List)
	 */
	public void assignUserGroups(User user, List<Group> groups)
			throws DAOException {
		List<Group> oldGroups = this.groupDAO.findByUser(user);
		for (Group oldGroup : oldGroups) {
			boolean found = false;
			for (Group newGroup : groups) {
				if (oldGroup.idEquals(newGroup)) {
					found = true;
					break;
				}
			}
			if (!found) {
				oldGroup.removeUser(user);
				this.groupDAO.update(oldGroup);
			}
		}
		for (Group group : groups) {
			if (!group.contains(user)) {
				group.addUser(user);
				this.groupDAO.update(group);
			}
		}
	}

	/* (non-Javadoc)
	 * @see whf.framework.auth.service.UserService#assignUserRoles(whf.framework.auth.entity.User, java.util.List)
	 */
	/* (non-Javadoc)
	 * @see whf.framework.security.service.UserService#assignUserRoles(whf.framework.security.entity.User, java.util.List)
	 */
	public void assignUserRoles(User user, List<Role> roles) throws DAOException {
		List<Role> oldRoles = this.roleDAO.findByUser(user);
		for (Role oldRole : oldRoles) {
			boolean found = false;
			for (Role newRole : roles) {
				if (oldRole.idEquals(newRole)) {
					found = true;
					break;
				}
			}
			if (!found) {
				oldRole.removeUser(user);
				this.roleDAO.update(oldRole);
			}
		}
		for (Role role : roles) {
			if (!role.contains(user)) {
				role.addUser(user);
				this.roleDAO.update(role);
			}
		}
	}

	public void activate(User user) throws DAOException {
		user.setAccountNonExpired(true);
		user.setAccountNonLocked(true);
		user.setCredentialsNonExpired(true);
		user.setEnabled(true);
		this.userDAO.update(user);
	}

	/* (non-Javadoc)
	 * @see whf.framework.security.service.UserService#deactivate(whf.framework.security.entity.User)
	 */
	public void deactivate(User user) throws DAOException {
		user.setAccountNonExpired(true);
		user.setAccountNonLocked(false);
		user.setCredentialsNonExpired(true);
		user.setEnabled(false);
		this.userDAO.update(user);
	}

}